#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include "Thread.hpp"
#include "LockGuard.hpp"

int ticket = 100;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //全局或静态的锁不销毁，用宏初始化即可

void* routine(void* args)
{
    while (1)
    {
        {
            //{}块内是临界区，LockGuard的生命周期随{}
            //进{，构造，加锁
            //出}，析构，解锁
            LockGuard lockGuard(&mutex); 
            if (ticket > 0)
            {
                usleep(1000);
                printf("sells ticket:%d\n", ticket);
                ticket--;
            }
            else
            {
                break;
            } 
        }
    }
}

int main()
{
    std::string name1 = getThreadName();
    Thread<pthread_mutex_t*> t1(name1, routine, &mutex);
    t1.start();

    std::string name2 = getThreadName();
    Thread<pthread_mutex_t*> t2(name2, routine, &mutex);
    t2.start();

    std::string name3 = getThreadName();
    Thread<pthread_mutex_t*> t3(name3, routine, &mutex);
    t3.start();

    std::string name4 = getThreadName();
    Thread<pthread_mutex_t*> t4(name4, routine, &mutex);
    t4.start();

    t1.join();
    t2.join();
    t3.join();
    t4.join();
}






// int ticket = 100;

// //pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //全局或静态的锁不销毁，用宏初始化即可

// void* routine(pthread_mutex_t* mutex)
// {
//     while (1)
//     {
//         pthread_mutex_lock(mutex);
//         if (ticket > 0)
//         {
//             usleep(1000);
//             printf("sells ticket:%d\n", ticket);
//             ticket--;
//             pthread_mutex_unlock(mutex);
//         }
//         else
//         {
//             pthread_mutex_unlock(mutex);
//             break;
//         }
//     }
// }

// int main()
// {
//     pthread_mutex_t mutex;
//     pthread_mutex_init(&mutex, nullptr);

//     std::string name1 = getThreadName();
//     Thread<pthread_mutex_t*> t1(name1, routine, &mutex);
//     t1.start();

//     std::string name2 = getThreadName();
//     Thread<pthread_mutex_t*> t2(name2, routine, &mutex);
//     t2.start();

//     std::string name3 = getThreadName();
//     Thread<pthread_mutex_t*> t3(name3, routine, &mutex);
//     t3.start();

//     std::string name4 = getThreadName();
//     Thread<pthread_mutex_t*> t4(name4, routine, &mutex);
//     t4.start();

//     t1.join();
//     t2.join();
//     t3.join();
//     t4.join();

//     pthread_mutex_destroy(&mutex);
// }